/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup Codec
 * @{
 *
 * @brief Codec模块接口定义
 *
 * Codec模块涉及自定义类型、音视频编解码组件初始化、参数设置、数据的轮转和控制等。
 *
 * @since 3.1
 */

/**
 * @file codec_callback_if.h
 *
 * @brief 主要包括回调函数接口定义
 *
 * Codec模块事件上报、上报输入buffer和输出buffer处理完毕等接口定义。
 *
 * @since 3.1
 */

#ifndef CODEC_CALLBACK_TYPE_H
#define CODEC_CALLBACK_TYPE_H

#include <stdint.h>
#include <netinet/in.h>
#include "codec_component_type.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/**
 * @brief Codec回调接口定义
 *
 * 提供了以下3种回调函数:
 * 1.组件错误事件、命令完成事件、端口设置等事件回调, 详见{@link EventHandler};
 * 2.输入端口处理完buffer回调, 详见{@link EmptyBufferDone};
 * 3.输出端口填充完buffer回调, 详见{@link FillBufferDone};
 * 通过以下两种方式注册回调:
 * 1.创建组件时, 通过{@link CreateComponent}方法;
 * 2.当组件处于OMX_StateLoaded状态时, 通过{@link SetCallbacks}方法注册回调。
 */
struct CodecCallbackType {
    struct HdfRemoteService *remote;

    /**
     * @brief 事件上报
     *
     * 组件运行过程中向上报告错误事件、命令完成事件、端口设置更改事件等。
     * 当eEvent为OMX_EventCmdComplete, eventData为NULL, data1 数据为OMX_COMMANDTYPE,
     * 此时, 当data1为OMX_CommandStateSet, data2表示状态, 其它情况下, data2表示端口;
     * 当eEvent为OMX_EventError时, data1表示错误码, data2和eventData都为0;
     * 当eEvent为OMX_EventMark时, data1和data2都为0, eventData指向mark指针;
     * 当eEvent为OMX_EventPortSettingsChanged时, data1表示端口, data2和eventData为0;
     * 当eEvent为OMX_EventBufferFlag时, data1表示端口, data2表示flag, eventData为0;
     * 当eEvent为OMX_EventResourcesAcquired或OMX_EventDynamicResourcesAvailable时, data1、data2和eventData都为0。
     *
     * @param self 输入参数, 指向要操作的callback指针
     * @param appData 输入参数, 上层数据, 通常是设置回调时给入的上层实例
     * @param appDataLen 输入参数, appData字节数
     * @param eEvent 输入参数, 要通知的事件类型, 详见{@link OMX_EVENTTYPE}
     * @param data1 输入参数, 事件上报携带的数据1
     * @param data2 输入参数, 事件上报携带的数据2
     * @param eventData 输入参数, 事件上报携带的数据信息
     * @param eventDataLen 输入参数, eventData字节数
     *
     * @return HDF_SUCCESS 表示事件上报成功
     * @return HDF_ERR_INVALID_PARAM 表示参数无效, 事件上报失败
     * @return HDF_ERR_INVALID_OBJECT 表示对象无效, 事件上报失败
     * @return HDF_ERR_MALLOC_FAIL 表示申请内存失败, 事件上报失败
     */
    int32_t (*EventHandler)(struct CodecCallbackType *self, int8_t *appData, uint32_t appDataLen,
        enum OMX_EVENTTYPE eEvent, uint32_t data1, uint32_t data2, int8_t *eventData, uint32_t eventDataLen);

    /**
     * @brief 上报输入buffer编码或者解码处理完毕
     *
     * 组件运行过程中向上报告输入buffer已经使用完毕。
     *
     * @param self 输入参数, 指向要操作的callback指针
     * @param appData 输入参数, 上层数据, 通常是设置回调时给入的上层实例
     * @param appDataLen 输入参数, appData字节数
     * @param buffer 输入参数, 已经处理完毕的输入buffer信息{@link OmxCodecBuffer}
     * 
     * @return HDF_SUCCESS 表示上报成功
     * @return HDF_ERR_INVALID_PARAM 表示参数无效, 上报失败
     * @return HDF_ERR_INVALID_OBJECT 表示对象无效, 上报失败
     * @return HDF_ERR_MALLOC_FAIL 表示申请内存失败, 上报失败
     */
    int32_t (*EmptyBufferDone)(struct CodecCallbackType *self, int8_t *appData,
        uint32_t appDataLen, const struct OmxCodecBuffer *buffer);

    /**
     * @brief 上报输出buffer填充完毕
     *
     * 组件运行过程中向上报告输出buffer已经填充完毕。
     *
     * @param self 输入参数, 指向要操作的callback指针
     * @param appData 输入参数, 上层数据, 通常是设置回调时给入的上层实例
     * @param appDataLen 输入参数, appData字节数
     * @param buffer 输入参数, 已经填充完毕的buffer信息{@link OmxCodecBuffer}
     * 
     * @return HDF_SUCCESS 表示上报成功
     * @return HDF_ERR_INVALID_PARAM 表示参数无效, 上报失败
     * @return HDF_ERR_INVALID_OBJECT 表示对象无效, 上报失败
     * @return HDF_ERR_MALLOC_FAIL 表示申请内存失败, 上报失败
     */
    int32_t (*FillBufferDone)(struct CodecCallbackType *self, int8_t* appData,
        uint32_t appDataLen, struct OmxCodecBuffer* buffer);
};

/**
 * @brief 实例化CodecCallbackType对象
 *
 * @param remote 输入参数, 指向HdfRemoteService的指针
 *
 * @return 实例化CodecCallbackType对象
 */
struct CodecCallbackType *CodecCallbackTypeGet(struct HdfRemoteService *remote);

/**
 * @brief 释放CodecCallbackType对象
 *
 * @param instance 输入参数, 指向CodecCallbackType实例的指针
 */
void CodecCallbackTypeRelease(struct CodecCallbackType *instance);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif // CODEC_CALLBACK_TYPE_H